package com.smartleanx.module.hrm.service.employee;

import cn.hutool.core.collection.CollUtil;
import com.smartleanx.framework.common.enums.BizTypeEnum;
import com.smartleanx.framework.common.util.collection.CollectionUtils;
import com.smartleanx.module.bpm.enums.task.BpmProcessInstanceStatusEnum;
import com.smartleanx.module.hrm.app.empRisk.EmployeeRiskHandleService;
import com.smartleanx.module.hrm.controller.admin.employee.vo.EmployeeChangePostRespVO;
import com.smartleanx.module.hrm.controller.admin.employee.vo.EmployeeChangesFilesSaveReqVO;
import com.smartleanx.module.hrm.controller.admin.employee.vo.EmployeeTransferSimpleRespVo;
import com.smartleanx.module.hrm.dal.dataobject.employee.EmployeeRegularizeRecordDO;
import com.smartleanx.module.hrm.dal.dataobject.employee.EmployeeTransferRecordDO;
import com.smartleanx.module.hrm.dal.mysql.employee.EmployeeTransferRecordMapper;
import com.smartleanx.module.hrm.eums.employee.BizFileTypeEnum;
import com.smartleanx.module.hrm.eums.employee.ChangeTypeEnum;
import com.smartleanx.module.hrm.eums.employee.EmployeeRecordTypeEnum;
import com.smartleanx.module.hrm.eums.risk.RiskTypeEnum;
import com.smartleanx.module.hrm.intergration.FileServiceProvider;
import com.smartleanx.module.infra.api.file.dto.FileRefQueryDTO;
import com.smartleanx.module.infra.api.file.dto.FileRefRespDTO;
import com.smartleanx.module.infra.api.file.dto.FileRefSaveBaseDTO;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import org.springframework.validation.annotation.Validated;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.smartleanx.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.smartleanx.module.hrm.enums.ErrorCodeConstants.EMPLOYEE_TRANSFER_RECORD_NOT_EXISTS;
import static com.smartleanx.module.hrm.enums.ErrorCodeConstants.NO_EMPLOYEE_TRANSFER_RECORDS;

/**
 * 员工岗位/职位变更记录 Service 实现类
 *
 * @author 精益大师
 */
@Service
@Validated
public class EmployeeTransferRecordServiceImpl implements EmployeeTransferRecordService {
    @Resource
    private EmployeeTransferRecordMapper employeeTransferRecordMapper;

    @Resource
    private FileServiceProvider fileServiceProvider;

    @Resource
    @Lazy
    private EmployeeRiskHandleService employeeRiskHandleService;

    @Override
    public int createEmployeeChangeRecord(EmployeeTransferRecordDO employeeTransferRecordDO) {
        employeeTransferRecordDO.setId(null);
        return employeeTransferRecordMapper.insert(employeeTransferRecordDO);
    }

    @Override
    public int updateEmployeeTransferRecord(EmployeeTransferRecordDO updateObj) {

        int i = employeeTransferRecordMapper.updateById(updateObj);
        System.err.println("修改状态"+updateObj.getApproveResult()+"成功条数"+i);

        return 1 ;
    }

    @Override
    public EmployeeTransferRecordDO getEmployeeTransferRecord(Long id) {
        return employeeTransferRecordMapper.selectById(id);
    }

    @Override
    public List<EmployeeTransferRecordDO> getTransferRecordList(Long employeeId) {
        return employeeTransferRecordMapper.getTransferRecordList(employeeId);
    }

    @Override
    public List<EmployeeTransferRecordDO> getTransferRecordList(Collection<Long> employeeIdList, Integer changeType) {
        if (CollUtil.isEmpty(employeeIdList)) {
            return Collections.emptyList();
        }
        return employeeTransferRecordMapper.selectListByEmployeeId(employeeIdList, changeType);
    }

    @Override
    public List<EmployeeTransferRecordDO> getTransferRecordList() {

        List<EmployeeTransferRecordDO> list = employeeTransferRecordMapper.selectList();
        if (CollUtil.isEmpty(list)) {
            return Collections.emptyList();
        }
        // 按员工分类，取最后一条
        Map<Long, List<EmployeeTransferRecordDO>> listMap = CollectionUtils.convertMultiMap(list, EmployeeTransferRecordDO::getEmployeeId);
        List<EmployeeTransferRecordDO> recordList = new ArrayList<>();
        for (Long key : listMap.keySet()) {
            List<EmployeeTransferRecordDO> collect = listMap.get(key).stream().sorted(Comparator.comparing(EmployeeTransferRecordDO::getId).reversed()).collect(Collectors.toList());
            recordList.add(collect.get(0));
        }
        return recordList;
    }

    @Override
    public List<EmployeeTransferSimpleRespVo> changesGroups(Long employeeId, Integer bizFileType) {
        List<EmployeeTransferRecordDO> transferRecordList = employeeTransferRecordMapper.getTransferRecordList(employeeId)
                .stream().filter(t -> t.getCreateType().equals(EmployeeRecordTypeEnum.Management.getType()) ||
                        t.getApproveResult().equals(BpmProcessInstanceStatusEnum.APPROVE.getStatus())).collect(Collectors.toList());
        List<Integer> type = new ArrayList<>(Collections.singletonList(bizFileType));
        // 晋升
        if (bizFileType.equals(BizFileTypeEnum.PROMOTION_APPLICATION_FORM.getCode())) {
            transferRecordList.removeIf(t -> !t.getChangeType().equals(ChangeTypeEnum.PROMOTED.getCode()));
            type.add(BizFileTypeEnum.PROMOTION_APPLICATION_FORM_ADMIN.getCode());
            removeTransfer(transferRecordList, type);
        }
        // 调动
        if (bizFileType.equals(BizFileTypeEnum.TRANSFER_APPLICATION_FORM.getCode())) {
            transferRecordList.removeIf(t -> !t.getChangeType().equals(ChangeTypeEnum.CHANGE_POST.getCode()));
            type.add(BizFileTypeEnum.TRANSFER_APPLICATION_FORM_ADMIN.getCode());
            removeTransfer(transferRecordList, type);
        }
        // 降级
        if (bizFileType.equals(BizFileTypeEnum.DOWNGRADE_APPLICATION_FORM.getCode())) {
            transferRecordList.removeIf(t -> !t.getChangeType().equals(ChangeTypeEnum.DEGRADE.getCode()));
            type.add(BizFileTypeEnum.DOWNGRADE_APPLICATION_FORM_ADMIN.getCode());
            removeTransfer(transferRecordList, type);
        }

        if (CollUtil.isEmpty(transferRecordList)) {
            throw exception(NO_EMPLOYEE_TRANSFER_RECORDS);
        }

        List<EmployeeTransferRecordDO> collect = transferRecordList.stream().sorted(Comparator.comparing(EmployeeTransferRecordDO::getEffectTime).reversed()).collect(Collectors.toList());

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
        return CollectionUtils.convertList(collect, c -> {
            EmployeeTransferSimpleRespVo respVo = new EmployeeTransferSimpleRespVo();
            respVo.setEffectTime(c.getEffectTime().format(formatter));
            respVo.setId(c.getId());
            return respVo;
        });
    }

    /**
     * 去掉有附件的调动记录，只保留没有附件的
     *
     * @param transferRecordList
     * @param bizFileType
     */
    public void removeTransfer(List<EmployeeTransferRecordDO> transferRecordList, Collection<Integer> bizFileType) {
        // 附件相关
        FileRefQueryDTO refQueryDTO = new FileRefQueryDTO();
        refQueryDTO.setBizType(BizTypeEnum.EMPLOYEE_CHANGE_POST.getValue());
        refQueryDTO.setBizFileTypes(bizFileType);
        refQueryDTO.setBizRecordIds(CollectionUtils.convertList(transferRecordList, EmployeeTransferRecordDO::getId));
        List<FileRefRespDTO> fileRefRespDTOList = fileServiceProvider.getFileRef(refQueryDTO);
        Map<Long, List<FileRefRespDTO>> map = CollectionUtils.convertMultiMap(fileRefRespDTOList, FileRefRespDTO::getBizRecordId);
        List<EmployeeTransferRecordDO> removeList = new ArrayList<>();
        if (fileRefRespDTOList.size() > 0) {
            for (EmployeeTransferRecordDO recordDO : transferRecordList) {
                List<FileRefRespDTO> list = map.get(recordDO.getId());
                if (CollUtil.isNotEmpty(list)) {
                    removeList.add(recordDO);
                }
            }
            transferRecordList.removeAll(removeList);
        }
    }

    public void createChangesFiles(EmployeeChangesFilesSaveReqVO reqVO) {
        if (CollUtil.isNotEmpty(reqVO.getApplyFileIdList())) {
            EmployeeTransferRecordDO recordDO = employeeTransferRecordMapper.selectById(reqVO.getChangeId());
            List<FileRefSaveBaseDTO> fileRefList = CollectionUtils.convertList(reqVO.getApplyFileIdList(), fileId -> {
                FileRefSaveBaseDTO dto = new FileRefSaveBaseDTO();
                dto.setFileId(fileId);
                boolean[] bitTagArr = new boolean[1];
                bitTagArr[0] = true;
                dto.setBitTagArr(bitTagArr);
                // 晋升
                if (reqVO.getBizFileType().equals(BizFileTypeEnum.PROMOTION_APPLICATION_FORM.getCode())) {
                    dto.setBizFileType(BizFileTypeEnum.PROMOTION_APPLICATION_FORM_ADMIN.getCode());
                }
                // 调动
                if (reqVO.getBizFileType().equals(BizFileTypeEnum.TRANSFER_APPLICATION_FORM.getCode())) {
                    dto.setBizFileType(BizFileTypeEnum.TRANSFER_APPLICATION_FORM_ADMIN.getCode());
                }
                // 降级
                if (reqVO.getBizFileType().equals(BizFileTypeEnum.DOWNGRADE_APPLICATION_FORM.getCode())) {
                    dto.setBizFileType(BizFileTypeEnum.DOWNGRADE_APPLICATION_FORM_ADMIN.getCode());
                }
                return dto;
            });
            fileServiceProvider.createFileRefByBizTypeAndRecordId(fileRefList, BizTypeEnum.EMPLOYEE_CHANGE_POST.getValue(), reqVO.getChangeId());
            // 风险点检查
            List<Long> riskType = Stream.of(RiskTypeEnum.TRANSFER_APPLICATION_FORM.getCode(), RiskTypeEnum.DEMOTION_NOTICE_FORM.getCode()).collect(Collectors.toList());
            for (Long type : riskType) {
                employeeRiskHandleService.execute(Collections.singleton(recordDO.getEmployeeId()), type);
            }
        }


    }

    @Override
    public void deleteEmployeeTransferRecord(Long id) {
        employeeTransferRecordMapper.deleteById(id);
    }
}
